Skip to content

Conversation

@DrSergei
Copy link
Contributor

@DrSergei DrSergei commented Oct 20, 2025

This patch adds small workaround for issue. It looks like code compiled with gcc has lack of some important debug information (e.g. DW_TAG_template_type_parameter for allocator).

Example code:

#include <unordered_map>

int main() {
    std::unordered_map<int, int> map = {
        {1, 2}
    };
    return 0;
}

Output from llvm-dwarfdump for code compiled by GCC or Clang. I used system GCC (13.3.0) and Clang (18.1.3) on Ubuntu 24.04 (WSL).

GCC:

0x00001fcd:     DW_TAG_class_type
                  DW_AT_name	("allocator<std::pair<int const, int> >")
                  DW_AT_byte_size	(0x01)
                  DW_AT_decl_file	("/usr/include/c++/13/bits/allocator.h")
                  DW_AT_decl_line	(130)
                  DW_AT_decl_column	(11)
                  DW_AT_sibling	(0x0000207c)

0x00001fda:       DW_TAG_inheritance
                    DW_AT_type	(0x00001d0a "std::__new_allocator<std::pair<int const, int> >")
                    DW_AT_data_member_location	(0)
                    DW_AT_accessibility	(DW_ACCESS_public)

0x00001fe0:       DW_TAG_subprogram
                    DW_AT_external	(true)
                    DW_AT_name	("allocator")
                    DW_AT_decl_file	("/usr/include/c++/13/bits/allocator.h")
                    DW_AT_decl_line	(163)
                    DW_AT_decl_column	(7)
                    DW_AT_linkage_name	("_ZNSaISt4pairIKiiEEC4Ev")
                    DW_AT_accessibility	(DW_ACCESS_public)
                    DW_AT_declaration	(true)
                    DW_AT_object_pointer	(0x00001ff4)
                    DW_AT_sibling	(0x00001ffa)

0x00001ff4:         DW_TAG_formal_parameter
                      DW_AT_type	(0x00004eb9 "std::allocator<std::pair<int const, int> > *")
                      DW_AT_artificial	(true)

0x00001ff9:         NULL

0x00001ffa:       DW_TAG_subprogram
                    DW_AT_external	(true)
                    DW_AT_name	("allocator")
                    DW_AT_decl_file	("/usr/include/c++/13/bits/allocator.h")
                    DW_AT_decl_line	(167)
                    DW_AT_decl_column	(7)
                    DW_AT_linkage_name	("_ZNSaISt4pairIKiiEEC4ERKS2_")
                    DW_AT_accessibility	(DW_ACCESS_public)
                    DW_AT_declaration	(true)
                    DW_AT_object_pointer	(0x0000200e)
                    DW_AT_sibling	(0x00002019)

0x0000200e:         DW_TAG_formal_parameter
                      DW_AT_type	(0x00004eb9 "std::allocator<std::pair<int const, int> > *")
                      DW_AT_artificial	(true)

0x00002013:         DW_TAG_formal_parameter
                      DW_AT_type	(0x00004ec3 "const std::allocator<std::pair<int const, int> > &")

0x00002018:         NULL

0x00002019:       DW_TAG_subprogram
                    DW_AT_external	(true)
                    DW_AT_name	("operator=")
                    DW_AT_decl_file	("/usr/include/c++/13/bits/allocator.h")
                    DW_AT_decl_line	(172)
                    DW_AT_decl_column	(18)
                    DW_AT_linkage_name	("_ZNSaISt4pairIKiiEEaSERKS2_")
                    DW_AT_type	(0x00004ec8 "std::allocator<std::pair<int const, int> > &")
                    DW_AT_accessibility	(DW_ACCESS_public)
                    DW_AT_declaration	(true)
                    DW_AT_defaulted	(DW_DEFAULTED_in_class)
                    DW_AT_object_pointer	(0x00002031)
                    DW_AT_sibling	(0x0000203c)

0x00002031:         DW_TAG_formal_parameter
                      DW_AT_type	(0x00004eb9 "std::allocator<std::pair<int const, int> > *")
                      DW_AT_artificial	(true)

0x00002036:         DW_TAG_formal_parameter
                      DW_AT_type	(0x00004ec3 "const std::allocator<std::pair<int const, int> > &")

0x0000203b:         NULL

0x0000203c:       DW_TAG_subprogram
                    DW_AT_external	(true)
                    DW_AT_name	("~allocator")
                    DW_AT_decl_file	("/usr/include/c++/13/bits/allocator.h")
                    DW_AT_decl_line	(184)
                    DW_AT_decl_column	(7)
                    DW_AT_linkage_name	("_ZNSaISt4pairIKiiEED4Ev")
                    DW_AT_accessibility	(DW_ACCESS_public)
                    DW_AT_declaration	(true)
                    DW_AT_object_pointer	(0x00002050)
                    DW_AT_sibling	(0x0000205b)

0x00002050:         DW_TAG_formal_parameter
                      DW_AT_type	(0x00004eb9 "std::allocator<std::pair<int const, int> > *")
                      DW_AT_artificial	(true)

0x00002055:         DW_TAG_formal_parameter
                      DW_AT_type	(0x00004cab "int")
                      DW_AT_artificial	(true)

0x0000205a:         NULL

Clang:

0x00001a6e:     DW_TAG_class_type
                  DW_AT_calling_convention	(DW_CC_pass_by_reference)
                  DW_AT_name	("allocator<std::pair<const int, int> >")
                  DW_AT_byte_size	(0x01)
                  DW_AT_decl_file	("/usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/allocator.h")
                  DW_AT_decl_line	(130)

0x00001a74:       DW_TAG_template_type_parameter
                    DW_AT_type	(0x00000dec "std::pair<const int, int>")
                    DW_AT_name	("_Tp")

0x00001a7a:       DW_TAG_inheritance
                    DW_AT_type	(0x00001ad5 "std::__allocator_base<std::pair<const int, int> >")
                    DW_AT_data_member_location	(0x00)
                    DW_AT_accessibility	(DW_ACCESS_public)

0x00001a81:       DW_TAG_subprogram
                    DW_AT_name	("allocator")
                    DW_AT_decl_file	("/usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/allocator.h")
                    DW_AT_decl_line	(163)
                    DW_AT_declaration	(true)
                    DW_AT_external	(true)
                    DW_AT_accessibility	(DW_ACCESS_public)

0x00001a86:         DW_TAG_formal_parameter
                      DW_AT_type	(0x00002dd1 "std::allocator<std::pair<const int, int> > *")
                      DW_AT_artificial	(true)

0x00001a8b:         NULL

0x00001a8c:       DW_TAG_subprogram
                    DW_AT_name	("allocator")
                    DW_AT_decl_file	("/usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/allocator.h")
                    DW_AT_decl_line	(167)
                    DW_AT_declaration	(true)
                    DW_AT_external	(true)
                    DW_AT_accessibility	(DW_ACCESS_public)

0x00001a91:         DW_TAG_formal_parameter
                      DW_AT_type	(0x00002dd1 "std::allocator<std::pair<const int, int> > *")
                      DW_AT_artificial	(true)

0x00001a96:         DW_TAG_formal_parameter
                      DW_AT_type	(0x00002dd6 "const std::allocator<std::pair<const int, int> > &")

0x00001a9b:         NULL

0x00001a9c:       DW_TAG_subprogram
                    DW_AT_linkage_name	("_ZNSaISt4pairIKiiEEaSERKS2_")
                    DW_AT_name	("operator=")
                    DW_AT_decl_file	("/usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/allocator.h")
                    DW_AT_decl_line	(172)
                    DW_AT_type	(0x00002de0 "std::allocator<std::pair<const int, int> > &")
                    DW_AT_declaration	(true)
                    DW_AT_external	(true)
                    DW_AT_accessibility	(DW_ACCESS_public)

0x00001aa6:         DW_TAG_formal_parameter
                      DW_AT_type	(0x00002dd1 "std::allocator<std::pair<const int, int> > *")
                      DW_AT_artificial	(true)

0x00001aab:         DW_TAG_formal_parameter
                      DW_AT_type	(0x00002dd6 "const std::allocator<std::pair<const int, int> > &")

0x00001ab0:         NULL

0x00001ab1:       DW_TAG_subprogram
                    DW_AT_name	("~allocator")
                    DW_AT_decl_file	("/usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/allocator.h")
                    DW_AT_decl_line	(184)
                    DW_AT_declaration	(true)
                    DW_AT_external	(true)
                    DW_AT_accessibility	(DW_ACCESS_public)

0x00001ab6:         DW_TAG_formal_parameter
                      DW_AT_type	(0x00002dd1 "std::allocator<std::pair<const int, int> > *")
                      DW_AT_artificial	(true)

0x00001abb:         NULL

I propose to add fallback implementation based on type of _M_h.

@llvmbot
Copy link
Member

llvmbot commented Oct 20, 2025

@llvm/pr-subscribers-lldb

Author: Sergei Druzhkov (DrSergei)

Changes

This patch adds small workaround for issue. It looks like code compiled with gcc has lack of some important debug information (e.g. DW_TAG_template_type_parameter for allocator).

Example code:

#include &lt;unordered_map&gt;

int main() {
    std::unordered_map&lt;int, int&gt; map = {
        {1, 2}
    };
    return 0;
}

Output from llvm-dwarfdump for code compiled by GCC or Clang.

GCC:

0x00001fcd:     DW_TAG_class_type
                  DW_AT_name	("allocator&lt;std::pair&lt;int const, int&gt; &gt;")
                  DW_AT_byte_size	(0x01)
                  DW_AT_decl_file	("/usr/include/c++/13/bits/allocator.h")
                  DW_AT_decl_line	(130)
                  DW_AT_decl_column	(11)
                  DW_AT_sibling	(0x0000207c)

0x00001fda:       DW_TAG_inheritance
                    DW_AT_type	(0x00001d0a "std::__new_allocator&lt;std::pair&lt;int const, int&gt; &gt;")
                    DW_AT_data_member_location	(0)
                    DW_AT_accessibility	(DW_ACCESS_public)

0x00001fe0:       DW_TAG_subprogram
                    DW_AT_external	(true)
                    DW_AT_name	("allocator")
                    DW_AT_decl_file	("/usr/include/c++/13/bits/allocator.h")
                    DW_AT_decl_line	(163)
                    DW_AT_decl_column	(7)
                    DW_AT_linkage_name	("_ZNSaISt4pairIKiiEEC4Ev")
                    DW_AT_accessibility	(DW_ACCESS_public)
                    DW_AT_declaration	(true)
                    DW_AT_object_pointer	(0x00001ff4)
                    DW_AT_sibling	(0x00001ffa)

0x00001ff4:         DW_TAG_formal_parameter
                      DW_AT_type	(0x00004eb9 "std::allocator&lt;std::pair&lt;int const, int&gt; &gt; *")
                      DW_AT_artificial	(true)

0x00001ff9:         NULL

0x00001ffa:       DW_TAG_subprogram
                    DW_AT_external	(true)
                    DW_AT_name	("allocator")
                    DW_AT_decl_file	("/usr/include/c++/13/bits/allocator.h")
                    DW_AT_decl_line	(167)
                    DW_AT_decl_column	(7)
                    DW_AT_linkage_name	("_ZNSaISt4pairIKiiEEC4ERKS2_")
                    DW_AT_accessibility	(DW_ACCESS_public)
                    DW_AT_declaration	(true)
                    DW_AT_object_pointer	(0x0000200e)
                    DW_AT_sibling	(0x00002019)

0x0000200e:         DW_TAG_formal_parameter
                      DW_AT_type	(0x00004eb9 "std::allocator&lt;std::pair&lt;int const, int&gt; &gt; *")
                      DW_AT_artificial	(true)

0x00002013:         DW_TAG_formal_parameter
                      DW_AT_type	(0x00004ec3 "const std::allocator&lt;std::pair&lt;int const, int&gt; &gt; &amp;")

0x00002018:         NULL

0x00002019:       DW_TAG_subprogram
                    DW_AT_external	(true)
                    DW_AT_name	("operator=")
                    DW_AT_decl_file	("/usr/include/c++/13/bits/allocator.h")
                    DW_AT_decl_line	(172)
                    DW_AT_decl_column	(18)
                    DW_AT_linkage_name	("_ZNSaISt4pairIKiiEEaSERKS2_")
                    DW_AT_type	(0x00004ec8 "std::allocator&lt;std::pair&lt;int const, int&gt; &gt; &amp;")
                    DW_AT_accessibility	(DW_ACCESS_public)
                    DW_AT_declaration	(true)
                    DW_AT_defaulted	(DW_DEFAULTED_in_class)
                    DW_AT_object_pointer	(0x00002031)
                    DW_AT_sibling	(0x0000203c)

0x00002031:         DW_TAG_formal_parameter
                      DW_AT_type	(0x00004eb9 "std::allocator&lt;std::pair&lt;int const, int&gt; &gt; *")
                      DW_AT_artificial	(true)

0x00002036:         DW_TAG_formal_parameter
                      DW_AT_type	(0x00004ec3 "const std::allocator&lt;std::pair&lt;int const, int&gt; &gt; &amp;")

0x0000203b:         NULL

0x0000203c:       DW_TAG_subprogram
                    DW_AT_external	(true)
                    DW_AT_name	("~allocator")
                    DW_AT_decl_file	("/usr/include/c++/13/bits/allocator.h")
                    DW_AT_decl_line	(184)
                    DW_AT_decl_column	(7)
                    DW_AT_linkage_name	("_ZNSaISt4pairIKiiEED4Ev")
                    DW_AT_accessibility	(DW_ACCESS_public)
                    DW_AT_declaration	(true)
                    DW_AT_object_pointer	(0x00002050)
                    DW_AT_sibling	(0x0000205b)

0x00002050:         DW_TAG_formal_parameter
                      DW_AT_type	(0x00004eb9 "std::allocator&lt;std::pair&lt;int const, int&gt; &gt; *")
                      DW_AT_artificial	(true)

0x00002055:         DW_TAG_formal_parameter
                      DW_AT_type	(0x00004cab "int")
                      DW_AT_artificial	(true)

0x0000205a:         NULL

Clang:

0x00001a6e:     DW_TAG_class_type
                  DW_AT_calling_convention	(DW_CC_pass_by_reference)
                  DW_AT_name	("allocator&lt;std::pair&lt;const int, int&gt; &gt;")
                  DW_AT_byte_size	(0x01)
                  DW_AT_decl_file	("/usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/allocator.h")
                  DW_AT_decl_line	(130)

0x00001a74:       DW_TAG_template_type_parameter
                    DW_AT_type	(0x00000dec "std::pair&lt;const int, int&gt;")
                    DW_AT_name	("_Tp")

0x00001a7a:       DW_TAG_inheritance
                    DW_AT_type	(0x00001ad5 "std::__allocator_base&lt;std::pair&lt;const int, int&gt; &gt;")
                    DW_AT_data_member_location	(0x00)
                    DW_AT_accessibility	(DW_ACCESS_public)

0x00001a81:       DW_TAG_subprogram
                    DW_AT_name	("allocator")
                    DW_AT_decl_file	("/usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/allocator.h")
                    DW_AT_decl_line	(163)
                    DW_AT_declaration	(true)
                    DW_AT_external	(true)
                    DW_AT_accessibility	(DW_ACCESS_public)

0x00001a86:         DW_TAG_formal_parameter
                      DW_AT_type	(0x00002dd1 "std::allocator&lt;std::pair&lt;const int, int&gt; &gt; *")
                      DW_AT_artificial	(true)

0x00001a8b:         NULL

0x00001a8c:       DW_TAG_subprogram
                    DW_AT_name	("allocator")
                    DW_AT_decl_file	("/usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/allocator.h")
                    DW_AT_decl_line	(167)
                    DW_AT_declaration	(true)
                    DW_AT_external	(true)
                    DW_AT_accessibility	(DW_ACCESS_public)

0x00001a91:         DW_TAG_formal_parameter
                      DW_AT_type	(0x00002dd1 "std::allocator&lt;std::pair&lt;const int, int&gt; &gt; *")
                      DW_AT_artificial	(true)

0x00001a96:         DW_TAG_formal_parameter
                      DW_AT_type	(0x00002dd6 "const std::allocator&lt;std::pair&lt;const int, int&gt; &gt; &amp;")

0x00001a9b:         NULL

0x00001a9c:       DW_TAG_subprogram
                    DW_AT_linkage_name	("_ZNSaISt4pairIKiiEEaSERKS2_")
                    DW_AT_name	("operator=")
                    DW_AT_decl_file	("/usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/allocator.h")
                    DW_AT_decl_line	(172)
                    DW_AT_type	(0x00002de0 "std::allocator&lt;std::pair&lt;const int, int&gt; &gt; &amp;")
                    DW_AT_declaration	(true)
                    DW_AT_external	(true)
                    DW_AT_accessibility	(DW_ACCESS_public)

0x00001aa6:         DW_TAG_formal_parameter
                      DW_AT_type	(0x00002dd1 "std::allocator&lt;std::pair&lt;const int, int&gt; &gt; *")
                      DW_AT_artificial	(true)

0x00001aab:         DW_TAG_formal_parameter
                      DW_AT_type	(0x00002dd6 "const std::allocator&lt;std::pair&lt;const int, int&gt; &gt; &amp;")

0x00001ab0:         NULL

0x00001ab1:       DW_TAG_subprogram
                    DW_AT_name	("~allocator")
                    DW_AT_decl_file	("/usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/allocator.h")
                    DW_AT_decl_line	(184)
                    DW_AT_declaration	(true)
                    DW_AT_external	(true)
                    DW_AT_accessibility	(DW_ACCESS_public)

0x00001ab6:         DW_TAG_formal_parameter
                      DW_AT_type	(0x00002dd1 "std::allocator&lt;std::pair&lt;const int, int&gt; &gt; *")
                      DW_AT_artificial	(true)

0x00001abb:         NULL

I propose to add fallback implementation based on type of _M_h.


Full diff: https://github.com/llvm/llvm-project/pull/164251.diff

1 Files Affected:

  • (modified) lldb/examples/synthetic/gnu_libstdcpp.py (+5)
diff --git a/lldb/examples/synthetic/gnu_libstdcpp.py b/lldb/examples/synthetic/gnu_libstdcpp.py
index f42a009c21f48..54d6248185fda 100644
--- a/lldb/examples/synthetic/gnu_libstdcpp.py
+++ b/lldb/examples/synthetic/gnu_libstdcpp.py
@@ -68,6 +68,11 @@ def extract_type(self):
         template_arg_num = type.GetNumberOfTemplateArguments() - 1
         allocator_type = type.GetTemplateArgumentType(template_arg_num)
         data_type = allocator_type.GetTemplateArgumentType(0)
+        if data_type.IsValid():
+            return data_type
+        type = self.head.GetType()
+        head_type = type.GetTypedefedType().GetTypedefedType()
+        data_type = head_type.GetTemplateArgumentType(1)
         return data_type
 
     def update(self):

Comment on lines 71 to 72
if data_type.IsValid():
return data_type
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we just remove this codepath and use the same codepath for Clang and GCC? That way it's also going to be tested on CI.

Comment on lines 73 to 74
type = self.head.GetType()
head_type = type.GetTypedefedType().GetTypedefedType()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
type = self.head.GetType()
head_type = type.GetTypedefedType().GetTypedefedType()
head_type = self.head.GetType().GetCanonicalType()

@Michael137
Copy link
Member

Can you file a bug on GCC about the missing template parameter?

@DrSergei DrSergei force-pushed the fix-unordered-map-synthetic-child-provider branch from e63e7da to efe6fbd Compare October 21, 2025 17:17
@DrSergei
Copy link
Contributor Author

I am not sure that there is a reliable approach here so it may be better to have two ways to get data type. The current solution works both for gcc and clang on my laptop, but it might depend on the compiler version. I found an old review where mentioned that omitting certain fields can be an intentional debug info optimization. I suspect GCC developers may have the same intention. This bug was already submitted to GCC, but there has been no feedback.

Failed AArch64 pipeline is not caused by this patch. It looks like there is a problem with infrastructure.

@Michael137
Copy link
Member

I am not sure that there is a reliable approach here so it may be better to have two ways to get data type. The current solution works both for gcc and clang on my laptop, but it might depend on the compiler version.

That's a fair point. But just for testability, I think it's best if we use the same method of retrieval here. If Clang decides to omit those typedefs at some point then we can add another branch. But don't feel strongly about it

I found an old review where mentioned that omitting certain fields can be an intentional debug info optimization.

That is true, but I've only seen this apply to types or functions. First time I'm seeing this for other kinds of tags like DW_TAG_template_type_parameter (@dwblaikie @adrian-prantl is this a size optimisation you are aware of?)

This bug was already submitted to GCC, but there has been no feedback.

Good find. Interesting that this applies to std::allocator again.

@dwblaikie
Copy link
Collaborator

Oh, yeah, GCC doesn't produce DW_TAG_template_type_parameter for unnamed template type parameters - yeah, it'd be a valid size optimization for them (relying on the uniqueness/identity of the DW_AT_name, I guess, for any type equivalence checking) - anything that can pull in more types into DWARF can be quite expensive (pulling in a whole type subgraph) so I could totally believe they did this for size optimization reasons.

We (Clang/LLVM) don't put any DW_TAG_template_type_parameters on (non-defining) declarations of template entities - except on SCE and when using Simplified Template Names. But we do put them all on for definitions, whether or not they're named/used.

@Michael137
Copy link
Member

Oh, yeah, GCC doesn't produce DW_TAG_template_type_parameter for unnamed template type parameters - yeah, it'd be a valid size optimization for them (relying on the uniqueness/identity of the DW_AT_name, I guess, for any type equivalence checking) - anything that can pull in more types into DWARF can be quite expensive (pulling in a whole type subgraph) so I could totally believe they did this for size optimization reasons.

We (Clang/LLVM) don't put any DW_TAG_template_type_parameters on (non-defining) declarations of template entities - except on SCE and when using Simplified Template Names. But we do put them all on for definitions, whether or not they're named/used.

Thanks for confirming!

@DrSergei want me to merge this?

@DrSergei
Copy link
Contributor Author

Oh, yeah, GCC doesn't produce DW_TAG_template_type_parameter for unnamed template type parameters - yeah, it'd be a valid size optimization for them (relying on the uniqueness/identity of the DW_AT_name, I guess, for any type equivalence checking) - anything that can pull in more types into DWARF can be quite expensive (pulling in a whole type subgraph) so I could totally believe they did this for size optimization reasons.
We (Clang/LLVM) don't put any DW_TAG_template_type_parameters on (non-defining) declarations of template entities - except on SCE and when using Simplified Template Names. But we do put them all on for definitions, whether or not they're named/used.

Thanks for confirming!

@DrSergei want me to merge this?

Yes, thanks a lot

@Michael137 Michael137 merged commit f4e77e9 into llvm:main Oct 29, 2025
13 of 14 checks passed
aokblast pushed a commit to aokblast/llvm-project that referenced this pull request Oct 30, 2025
This patch adds small workaround for
[issue](llvm#152504). It looks
like code compiled with gcc has lack of some important debug information
(e.g. DW_TAG_template_type_parameter for allocator).

Example code:
```cpp
#include <unordered_map>

int main() {
    std::unordered_map<int, int> map = {
        {1, 2}
    };
    return 0;
}
```

Output from `llvm-dwarfdump` for code compiled by GCC or Clang. I used
system GCC (13.3.0) and Clang (18.1.3) on Ubuntu 24.04 (WSL).

GCC:
```
0x00001fcd:     DW_TAG_class_type
                  DW_AT_name	("allocator<std::pair<int const, int> >")
                  DW_AT_byte_size	(0x01)
                  DW_AT_decl_file	("/usr/include/c++/13/bits/allocator.h")
                  DW_AT_decl_line	(130)
                  DW_AT_decl_column	(11)
                  DW_AT_sibling	(0x0000207c)

0x00001fda:       DW_TAG_inheritance
                    DW_AT_type	(0x00001d0a "std::__new_allocator<std::pair<int const, int> >")
                    DW_AT_data_member_location	(0)
                    DW_AT_accessibility	(DW_ACCESS_public)

0x00001fe0:       DW_TAG_subprogram
                    DW_AT_external	(true)
                    DW_AT_name	("allocator")
                    DW_AT_decl_file	("/usr/include/c++/13/bits/allocator.h")
                    DW_AT_decl_line	(163)
                    DW_AT_decl_column	(7)
                    DW_AT_linkage_name	("_ZNSaISt4pairIKiiEEC4Ev")
                    DW_AT_accessibility	(DW_ACCESS_public)
                    DW_AT_declaration	(true)
                    DW_AT_object_pointer	(0x00001ff4)
                    DW_AT_sibling	(0x00001ffa)

0x00001ff4:         DW_TAG_formal_parameter
                      DW_AT_type	(0x00004eb9 "std::allocator<std::pair<int const, int> > *")
                      DW_AT_artificial	(true)

0x00001ff9:         NULL

0x00001ffa:       DW_TAG_subprogram
                    DW_AT_external	(true)
                    DW_AT_name	("allocator")
                    DW_AT_decl_file	("/usr/include/c++/13/bits/allocator.h")
                    DW_AT_decl_line	(167)
                    DW_AT_decl_column	(7)
                    DW_AT_linkage_name	("_ZNSaISt4pairIKiiEEC4ERKS2_")
                    DW_AT_accessibility	(DW_ACCESS_public)
                    DW_AT_declaration	(true)
                    DW_AT_object_pointer	(0x0000200e)
                    DW_AT_sibling	(0x00002019)

0x0000200e:         DW_TAG_formal_parameter
                      DW_AT_type	(0x00004eb9 "std::allocator<std::pair<int const, int> > *")
                      DW_AT_artificial	(true)

0x00002013:         DW_TAG_formal_parameter
                      DW_AT_type	(0x00004ec3 "const std::allocator<std::pair<int const, int> > &")

0x00002018:         NULL

0x00002019:       DW_TAG_subprogram
                    DW_AT_external	(true)
                    DW_AT_name	("operator=")
                    DW_AT_decl_file	("/usr/include/c++/13/bits/allocator.h")
                    DW_AT_decl_line	(172)
                    DW_AT_decl_column	(18)
                    DW_AT_linkage_name	("_ZNSaISt4pairIKiiEEaSERKS2_")
                    DW_AT_type	(0x00004ec8 "std::allocator<std::pair<int const, int> > &")
                    DW_AT_accessibility	(DW_ACCESS_public)
                    DW_AT_declaration	(true)
                    DW_AT_defaulted	(DW_DEFAULTED_in_class)
                    DW_AT_object_pointer	(0x00002031)
                    DW_AT_sibling	(0x0000203c)

0x00002031:         DW_TAG_formal_parameter
                      DW_AT_type	(0x00004eb9 "std::allocator<std::pair<int const, int> > *")
                      DW_AT_artificial	(true)

0x00002036:         DW_TAG_formal_parameter
                      DW_AT_type	(0x00004ec3 "const std::allocator<std::pair<int const, int> > &")

0x0000203b:         NULL

0x0000203c:       DW_TAG_subprogram
                    DW_AT_external	(true)
                    DW_AT_name	("~allocator")
                    DW_AT_decl_file	("/usr/include/c++/13/bits/allocator.h")
                    DW_AT_decl_line	(184)
                    DW_AT_decl_column	(7)
                    DW_AT_linkage_name	("_ZNSaISt4pairIKiiEED4Ev")
                    DW_AT_accessibility	(DW_ACCESS_public)
                    DW_AT_declaration	(true)
                    DW_AT_object_pointer	(0x00002050)
                    DW_AT_sibling	(0x0000205b)

0x00002050:         DW_TAG_formal_parameter
                      DW_AT_type	(0x00004eb9 "std::allocator<std::pair<int const, int> > *")
                      DW_AT_artificial	(true)

0x00002055:         DW_TAG_formal_parameter
                      DW_AT_type	(0x00004cab "int")
                      DW_AT_artificial	(true)

0x0000205a:         NULL
```

Clang:
```
0x00001a6e:     DW_TAG_class_type
                  DW_AT_calling_convention	(DW_CC_pass_by_reference)
                  DW_AT_name	("allocator<std::pair<const int, int> >")
                  DW_AT_byte_size	(0x01)
                  DW_AT_decl_file	("/usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/allocator.h")
                  DW_AT_decl_line	(130)

0x00001a74:       DW_TAG_template_type_parameter
                    DW_AT_type	(0x00000dec "std::pair<const int, int>")
                    DW_AT_name	("_Tp")

0x00001a7a:       DW_TAG_inheritance
                    DW_AT_type	(0x00001ad5 "std::__allocator_base<std::pair<const int, int> >")
                    DW_AT_data_member_location	(0x00)
                    DW_AT_accessibility	(DW_ACCESS_public)

0x00001a81:       DW_TAG_subprogram
                    DW_AT_name	("allocator")
                    DW_AT_decl_file	("/usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/allocator.h")
                    DW_AT_decl_line	(163)
                    DW_AT_declaration	(true)
                    DW_AT_external	(true)
                    DW_AT_accessibility	(DW_ACCESS_public)

0x00001a86:         DW_TAG_formal_parameter
                      DW_AT_type	(0x00002dd1 "std::allocator<std::pair<const int, int> > *")
                      DW_AT_artificial	(true)

0x00001a8b:         NULL

0x00001a8c:       DW_TAG_subprogram
                    DW_AT_name	("allocator")
                    DW_AT_decl_file	("/usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/allocator.h")
                    DW_AT_decl_line	(167)
                    DW_AT_declaration	(true)
                    DW_AT_external	(true)
                    DW_AT_accessibility	(DW_ACCESS_public)

0x00001a91:         DW_TAG_formal_parameter
                      DW_AT_type	(0x00002dd1 "std::allocator<std::pair<const int, int> > *")
                      DW_AT_artificial	(true)

0x00001a96:         DW_TAG_formal_parameter
                      DW_AT_type	(0x00002dd6 "const std::allocator<std::pair<const int, int> > &")

0x00001a9b:         NULL

0x00001a9c:       DW_TAG_subprogram
                    DW_AT_linkage_name	("_ZNSaISt4pairIKiiEEaSERKS2_")
                    DW_AT_name	("operator=")
                    DW_AT_decl_file	("/usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/allocator.h")
                    DW_AT_decl_line	(172)
                    DW_AT_type	(0x00002de0 "std::allocator<std::pair<const int, int> > &")
                    DW_AT_declaration	(true)
                    DW_AT_external	(true)
                    DW_AT_accessibility	(DW_ACCESS_public)

0x00001aa6:         DW_TAG_formal_parameter
                      DW_AT_type	(0x00002dd1 "std::allocator<std::pair<const int, int> > *")
                      DW_AT_artificial	(true)

0x00001aab:         DW_TAG_formal_parameter
                      DW_AT_type	(0x00002dd6 "const std::allocator<std::pair<const int, int> > &")

0x00001ab0:         NULL

0x00001ab1:       DW_TAG_subprogram
                    DW_AT_name	("~allocator")
                    DW_AT_decl_file	("/usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/allocator.h")
                    DW_AT_decl_line	(184)
                    DW_AT_declaration	(true)
                    DW_AT_external	(true)
                    DW_AT_accessibility	(DW_ACCESS_public)

0x00001ab6:         DW_TAG_formal_parameter
                      DW_AT_type	(0x00002dd1 "std::allocator<std::pair<const int, int> > *")
                      DW_AT_artificial	(true)

0x00001abb:         NULL
```

I propose to add fallback implementation based on type of `_M_h`.
DEBADRIBASAK pushed a commit to DEBADRIBASAK/llvm-project that referenced this pull request Nov 3, 2025
This patch adds small workaround for
[issue](llvm#152504). It looks
like code compiled with gcc has lack of some important debug information
(e.g. DW_TAG_template_type_parameter for allocator).

Example code:
```cpp
#include <unordered_map>

int main() {
    std::unordered_map<int, int> map = {
        {1, 2}
    };
    return 0;
}
```

Output from `llvm-dwarfdump` for code compiled by GCC or Clang. I used
system GCC (13.3.0) and Clang (18.1.3) on Ubuntu 24.04 (WSL).

GCC:
```
0x00001fcd:     DW_TAG_class_type
                  DW_AT_name	("allocator<std::pair<int const, int> >")
                  DW_AT_byte_size	(0x01)
                  DW_AT_decl_file	("/usr/include/c++/13/bits/allocator.h")
                  DW_AT_decl_line	(130)
                  DW_AT_decl_column	(11)
                  DW_AT_sibling	(0x0000207c)

0x00001fda:       DW_TAG_inheritance
                    DW_AT_type	(0x00001d0a "std::__new_allocator<std::pair<int const, int> >")
                    DW_AT_data_member_location	(0)
                    DW_AT_accessibility	(DW_ACCESS_public)

0x00001fe0:       DW_TAG_subprogram
                    DW_AT_external	(true)
                    DW_AT_name	("allocator")
                    DW_AT_decl_file	("/usr/include/c++/13/bits/allocator.h")
                    DW_AT_decl_line	(163)
                    DW_AT_decl_column	(7)
                    DW_AT_linkage_name	("_ZNSaISt4pairIKiiEEC4Ev")
                    DW_AT_accessibility	(DW_ACCESS_public)
                    DW_AT_declaration	(true)
                    DW_AT_object_pointer	(0x00001ff4)
                    DW_AT_sibling	(0x00001ffa)

0x00001ff4:         DW_TAG_formal_parameter
                      DW_AT_type	(0x00004eb9 "std::allocator<std::pair<int const, int> > *")
                      DW_AT_artificial	(true)

0x00001ff9:         NULL

0x00001ffa:       DW_TAG_subprogram
                    DW_AT_external	(true)
                    DW_AT_name	("allocator")
                    DW_AT_decl_file	("/usr/include/c++/13/bits/allocator.h")
                    DW_AT_decl_line	(167)
                    DW_AT_decl_column	(7)
                    DW_AT_linkage_name	("_ZNSaISt4pairIKiiEEC4ERKS2_")
                    DW_AT_accessibility	(DW_ACCESS_public)
                    DW_AT_declaration	(true)
                    DW_AT_object_pointer	(0x0000200e)
                    DW_AT_sibling	(0x00002019)

0x0000200e:         DW_TAG_formal_parameter
                      DW_AT_type	(0x00004eb9 "std::allocator<std::pair<int const, int> > *")
                      DW_AT_artificial	(true)

0x00002013:         DW_TAG_formal_parameter
                      DW_AT_type	(0x00004ec3 "const std::allocator<std::pair<int const, int> > &")

0x00002018:         NULL

0x00002019:       DW_TAG_subprogram
                    DW_AT_external	(true)
                    DW_AT_name	("operator=")
                    DW_AT_decl_file	("/usr/include/c++/13/bits/allocator.h")
                    DW_AT_decl_line	(172)
                    DW_AT_decl_column	(18)
                    DW_AT_linkage_name	("_ZNSaISt4pairIKiiEEaSERKS2_")
                    DW_AT_type	(0x00004ec8 "std::allocator<std::pair<int const, int> > &")
                    DW_AT_accessibility	(DW_ACCESS_public)
                    DW_AT_declaration	(true)
                    DW_AT_defaulted	(DW_DEFAULTED_in_class)
                    DW_AT_object_pointer	(0x00002031)
                    DW_AT_sibling	(0x0000203c)

0x00002031:         DW_TAG_formal_parameter
                      DW_AT_type	(0x00004eb9 "std::allocator<std::pair<int const, int> > *")
                      DW_AT_artificial	(true)

0x00002036:         DW_TAG_formal_parameter
                      DW_AT_type	(0x00004ec3 "const std::allocator<std::pair<int const, int> > &")

0x0000203b:         NULL

0x0000203c:       DW_TAG_subprogram
                    DW_AT_external	(true)
                    DW_AT_name	("~allocator")
                    DW_AT_decl_file	("/usr/include/c++/13/bits/allocator.h")
                    DW_AT_decl_line	(184)
                    DW_AT_decl_column	(7)
                    DW_AT_linkage_name	("_ZNSaISt4pairIKiiEED4Ev")
                    DW_AT_accessibility	(DW_ACCESS_public)
                    DW_AT_declaration	(true)
                    DW_AT_object_pointer	(0x00002050)
                    DW_AT_sibling	(0x0000205b)

0x00002050:         DW_TAG_formal_parameter
                      DW_AT_type	(0x00004eb9 "std::allocator<std::pair<int const, int> > *")
                      DW_AT_artificial	(true)

0x00002055:         DW_TAG_formal_parameter
                      DW_AT_type	(0x00004cab "int")
                      DW_AT_artificial	(true)

0x0000205a:         NULL
```

Clang:
```
0x00001a6e:     DW_TAG_class_type
                  DW_AT_calling_convention	(DW_CC_pass_by_reference)
                  DW_AT_name	("allocator<std::pair<const int, int> >")
                  DW_AT_byte_size	(0x01)
                  DW_AT_decl_file	("/usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/allocator.h")
                  DW_AT_decl_line	(130)

0x00001a74:       DW_TAG_template_type_parameter
                    DW_AT_type	(0x00000dec "std::pair<const int, int>")
                    DW_AT_name	("_Tp")

0x00001a7a:       DW_TAG_inheritance
                    DW_AT_type	(0x00001ad5 "std::__allocator_base<std::pair<const int, int> >")
                    DW_AT_data_member_location	(0x00)
                    DW_AT_accessibility	(DW_ACCESS_public)

0x00001a81:       DW_TAG_subprogram
                    DW_AT_name	("allocator")
                    DW_AT_decl_file	("/usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/allocator.h")
                    DW_AT_decl_line	(163)
                    DW_AT_declaration	(true)
                    DW_AT_external	(true)
                    DW_AT_accessibility	(DW_ACCESS_public)

0x00001a86:         DW_TAG_formal_parameter
                      DW_AT_type	(0x00002dd1 "std::allocator<std::pair<const int, int> > *")
                      DW_AT_artificial	(true)

0x00001a8b:         NULL

0x00001a8c:       DW_TAG_subprogram
                    DW_AT_name	("allocator")
                    DW_AT_decl_file	("/usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/allocator.h")
                    DW_AT_decl_line	(167)
                    DW_AT_declaration	(true)
                    DW_AT_external	(true)
                    DW_AT_accessibility	(DW_ACCESS_public)

0x00001a91:         DW_TAG_formal_parameter
                      DW_AT_type	(0x00002dd1 "std::allocator<std::pair<const int, int> > *")
                      DW_AT_artificial	(true)

0x00001a96:         DW_TAG_formal_parameter
                      DW_AT_type	(0x00002dd6 "const std::allocator<std::pair<const int, int> > &")

0x00001a9b:         NULL

0x00001a9c:       DW_TAG_subprogram
                    DW_AT_linkage_name	("_ZNSaISt4pairIKiiEEaSERKS2_")
                    DW_AT_name	("operator=")
                    DW_AT_decl_file	("/usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/allocator.h")
                    DW_AT_decl_line	(172)
                    DW_AT_type	(0x00002de0 "std::allocator<std::pair<const int, int> > &")
                    DW_AT_declaration	(true)
                    DW_AT_external	(true)
                    DW_AT_accessibility	(DW_ACCESS_public)

0x00001aa6:         DW_TAG_formal_parameter
                      DW_AT_type	(0x00002dd1 "std::allocator<std::pair<const int, int> > *")
                      DW_AT_artificial	(true)

0x00001aab:         DW_TAG_formal_parameter
                      DW_AT_type	(0x00002dd6 "const std::allocator<std::pair<const int, int> > &")

0x00001ab0:         NULL

0x00001ab1:       DW_TAG_subprogram
                    DW_AT_name	("~allocator")
                    DW_AT_decl_file	("/usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/allocator.h")
                    DW_AT_decl_line	(184)
                    DW_AT_declaration	(true)
                    DW_AT_external	(true)
                    DW_AT_accessibility	(DW_ACCESS_public)

0x00001ab6:         DW_TAG_formal_parameter
                      DW_AT_type	(0x00002dd1 "std::allocator<std::pair<const int, int> > *")
                      DW_AT_artificial	(true)

0x00001abb:         NULL
```

I propose to add fallback implementation based on type of `_M_h`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants